package xpn.platform.common.config;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.web.servlet.AdviceFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Shiro跨域请求过滤：如果是Options请求，则不做权限检查；
 * 如果是跨域请求，则在response的Headers中设置安全控制信息，否则axios不能正确检测。
 * 
 * @author bobatkm Sep 21, 2017
 *
 */
@Component
public class ShiroAdviceFilter extends AdviceFilter {

	@Override
	protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception {
		HttpServletRequest httpRequest = WebUtils.toHttp(request);
		HttpServletResponse httpResponse = WebUtils.toHttp(response);

		String origin = httpRequest.getHeader("Origin");
		if (!"".equals(origin)) { // 如果是跨域请求，在响应中设置安全Headers
			String headers = httpRequest.getHeader("Access-Control-Request-Headers");
			httpResponse.setHeader("Access-control-Allow-Origin", origin);
			httpResponse.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST, GET, PUT, PATCH, DELETE");
			httpResponse.setHeader("Access-Control-Allow-Headers",
					"xpnToken, JSESSIONID" + (headers == null ? "" : "," + headers));
		}

		// 如果是跨域的Options请求，不做安全检查，直接返回OK
		if (httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
			httpResponse.setStatus(HttpStatus.OK.value());
			return false;
		}

		return super.preHandle(request, response);
	}
}